﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using RBAC;
using RBAC.ORM;

namespace RBAC.APP
{
    public class Operator
    {
        #region Fileds
        /// <summary>
        /// 计数器
        /// </summary>
        private decimal id;
        /// <summary>
        /// 计数器
        /// </summary>
        public decimal Id
        {
            get { return id; }
            //set { id = value; }
        }
        /// <summary>
        /// 用户Id
        /// </summary>
        private string userId;
        /// <summary>
        /// 用户Id
        /// </summary>
        public string UserId
        {
            get { return userId; }
            //set { userId = value; }
        }
        /// <summary>
        /// 对象类型
        /// </summary>
        private ObjectType objectType;
        /// <summary>
        /// 对象类型
        /// </summary>
        public ObjectType ObjectType
        {
            get { return objectType; }
            //set { objectType = value; }
        }
        /// <summary>
        /// 内容
        /// </summary>
        private string content;
        /// <summary>
        /// 内容
        /// </summary>
        public string Content
        {
            get { return content; }
            //set { content = value; }
        }
        /// <summary>
        /// 最后更新时间
        /// </summary>
        private DateTime lastUpdateTime;
        /// <summary>
        /// 最后更新时间
        /// </summary>
        public DateTime LastUpdateTime
        {
            get { return lastUpdateTime; }
            //set { lastUpdateTime = value; }
        }
        #endregion Fields

        /// <summary>
        /// 做日志
        /// </summary>
        /// <param name="objectType">类型</param>
        /// <param name="content">内容</param>
        public static bool MakeLog(ObjectType objectType, string content)
        {
            //--------------------------------------------------------
            //在表SOperator中添加日志记录
            //参数（1）：ObjectType，不可为空，为4字代码
            //若为空，返回false；若不为空，对应objectType字段。
            //参数（2）：content，不可为空，为具体对象的内容。如修改了哪个栏目，增加了哪个用户
            //若为空，返回false；若不为空，对应contents字段，不能超过20个字符
            //参数（3）：userId，从RBACAPPSessionMapping.SessionUserId中获得
            //若获取异常，则调用RBACAPPDefaultValue.UserId_FailedToReadSessionMapping
            //参数（4）：lastUpdateTime，获得系统当前时间
            //返回（5）：bool
            //若成功，返回true
            //--------------------------------------------------------

            //看后删除此行：objectType.toString获得四字代码
            //看后删除此行：objectType.GetHashCode获得具体值
            if ((objectType != null) || (!string.IsNullOrEmpty(content) && content.Length <= 20))
            {
                try
                {
                    ORM.Model.SOperator modelOpt = new ORM.Model.SOperator();
                    ORM.DAL.SOperator dataOpt = new ORM.DAL.SOperator();
                    modelOpt.objectType = objectType.ToString();
                    modelOpt.contents = content;
                    modelOpt.id = modelOpt.id = dataOpt.GetMaxId() + 1;
                    try
                    {
                        modelOpt.userID = RBACAPPSessionMapping.SessionUserId;                    
                    }
                    catch (Exception)
                    {
                        modelOpt.userID = RBACAPPDefaultValue.UserId_FailedToReadSessionMapping;  
                    }
                    modelOpt.lastUpdateTime = DateTime.Now;
                    return dataOpt.Add(modelOpt);
                }
                catch (Exception)
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 阅读日志
        /// </summary>
        /// <param name="id">日志Id</param>
        public static Operator ReadLog(decimal id)
        {
            //--------------------------------------------------------
            //获得表：SOperator中的一个Log对象
            //参数（1）：id，日志的id。不可为空，不能为0。
            //若存在此Id，则从表中获得对应的字段；若不存在，则返回null
            //注意：从数据库中阅读出的objectType需要转换为枚举类型
            //注意：从数据库中阅读出的contents需要转换为文字类型
            //返回（2）：Operator对象
            //--------------------------------------------------------
            if (id != 0)
            {
                ORM.DAL.SOperator dataOpt = new ORM.DAL.SOperator();
                ORM.Model.SOperator modelOpt = new ORM.Model.SOperator();
                if (!dataOpt.Exists(id))
                {
                    return null;
                }
                else
                {
                    modelOpt = dataOpt.GetModel(id);
                    Operator myOpt = new Operator();
                    myOpt.id = modelOpt.id;
                    myOpt.userId = modelOpt.userID;
                    myOpt.content = modelOpt.contents.ToString();
                    myOpt.lastUpdateTime = modelOpt.lastUpdateTime;
                    myOpt.objectType = (ObjectType)Enum.Parse(typeof(ObjectType), modelOpt.objectType);
                    return myOpt;
                }
            }
            else
            {
                throw new Exception("Operator.ReadLog()错误:ID不可为0");
            }
        }

        /// <summary>
        /// 阅读日志
        /// </summary>
        /// <param name="howMany">数量</param>
        public static List<Operator> ReadLogs(int? howMany)
        {
            //--------------------------------------------------------
            //参考SearchLogs方法
            //--------------------------------------------------------

            return GetMyListOperatorsByWhereQStr("ALL", howMany);

            //return SearchLogs("", null, "", null, null, howMany);
        }

        /// <summary>
        /// 阅读日志
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="howMany">数量</param>
        public static List<Operator> ReadLogsbyUser(string userId, int? howMany)
        {
            //--------------------------------------------------------
            //参考SearchLogs方法
            //--------------------------------------------------------

            return GetMyListOperatorsByWhereQStr("userId = " + userId + " ORDER BY lastUpdateTime DESC", howMany);
            
            //return SearchLogs(userId, null, "", null, null, howMany);
        }

        /// <summary>
        /// 阅读日志
        /// </summary>
        /// <param name="objectType">对象类型</param>
        /// <param name="howMany">数量</param>
        public static List<Operator> ReadLogsbyObjectType(ObjectType objectType, int? howMany)
        {
            //--------------------------------------------------------
            //参考SearchLogs方法
            //--------------------------------------------------------

            return GetMyListOperatorsByWhereQStr("objectType = " + objectType + " ORDER BY lastUpdateTime DESC", howMany);
            
            //return SearchLogs("", objectType, "", null, null, howMany);
        }

        /// <summary>
        /// 阅读日志
        /// </summary>
        /// <param name="timeFrom">开始时间</param>
        /// <param name="timeTo">结束时间</param>
        /// <param name="howMany">数量</param>
        public static List<Operator> ReadLogsbyTime(System.DateTime? timeFrom, DateTime? timeTo, int? howMany)
        {
            //--------------------------------------------------------
            //参考SearchLogs方法
            //--------------------------------------------------------

            return GetMyListOperatorsByWhereQStr("lastUpdateTime > " + timeFrom + " AND lastUpdateTime < " + timeTo + " ORDER BY lastUpdateTime DESC", howMany);

            //return SearchLogs("", null, "", timeFrom, timeTo, howMany);
        }

        /// <summary>
        /// 搜索日志
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="objectType">对象类型</param>
        /// <param name="content">日志内容</param>
        /// <param name="timeFrom">开始时间</param>
        /// <param name="timeTo">结束时间</param>
        /// <param name="howMany">数量</param>
        public static List<Operator> SearchLogs(string userId, ObjectType objectType, string content, DateTime? timeFrom, DateTime? timeTo, int? howMany)
        {
            //--------------------------------------------------------
            //在表：SOperator中搜索相应的记录
            //参数（1）：userId，可以为空
            //若为空，则搜索结果与产生日志的用户userID无关；若不为空，则结果中的用户需符合
            //参数（2）：objectType，可以为空
            //若为空，则搜索结果与日志对象类型无关；若不为空，则结果中的对象类型需符合
            //参数（3）：content，可以为空
            //若为空，则搜索结果与日志内容无关；若不为空，则结果中的内容需符合
            //参数（4）（5）：timeFrom，可以为空；timeTo，可以为空
            //若为空，则不设定起始时间；若为空，则不设定结束时间
            //参数（6）：howMany，可以为空
            //若为空，则读取默认值RBACAPPDefaultValue.HowMany_LogsToRead
            //若读取上述参数异常，则默认为100
            //返回（7）：泛型Operator对象
            //在构建单个Operator对象时，调用ReadLog方法。若不存在搜索的结果，返回null
            //Operator对象集合以lastUpdateTime倒排序
            //--------------------------------------------------------
            
            List<Operator> myListOperators = new List<Operator>();
            ORM.DAL.SOperator dataOpt = new ORM.DAL.SOperator();
            
            if (howMany == null)
            {
                howMany = RBACAPPDefaultValue.HowMany_LogsToRead;
                if (howMany == null)
                {
                    howMany = 100;
                }
            }
            if (timeTo == null)
            {
                timeTo = DateTime.Now;
            }

            //string whereStr = "userId = " + userId + " AND objectTypte = " + objectType + " AND content = " + content + " AND lastUpdateTime > " + timeFrom + " AND lastUpdateTime < " + timeTo + " ORDER BY lastUpdateTime DESC";
                        
            if (string.IsNullOrEmpty(userId) && objectType == null && string.IsNullOrEmpty(content) && (timeFrom == null && timeTo == null))
            {
                //多个参数为空
                return GetMyListOperatorsByWhereQStr("ALL", howMany);
            }

            StringBuilder myWhereStr = new StringBuilder();
            if(!string.IsNullOrEmpty(userId))
            {
                myWhereStr.Append("userId = " + userId);
            }
            
            if (objectType != null)
            {
                myWhereStr.Append(" AND objectType = " + objectType);
            }

            if (!string.IsNullOrEmpty(content))
            {
                myWhereStr.Append(" AND content = " + content);
            }

            if (timeFrom == null)
            {
                myWhereStr.Append(" AND lastUpdateTime < " + timeTo);
            }
            else
            {
                myWhereStr.Append(" AND lastUpdateTime > " + timeFrom + " AND lastUpdateTime < " + timeTo);                
            }

            myWhereStr.Append(" ORDER BY lastUpdateTime DESC");
            string finalWhereStr = myWhereStr.ToString();
            finalWhereStr = finalWhereStr.Replace("where AND", "where"); //考虑userId为空后拼接字符串的情况
            return GetMyListOperatorsByWhereQStr(finalWhereStr, howMany);
            
        }

        //把操作封装起来～
        private static List<Operator> GetMyListOperatorsByWhereQStr(string whereQStr, int? howMany)
        {
            List<Operator> myListOperators = new List<Operator>();
            ORM.DAL.SOperator dataOpt = new ORM.DAL.SOperator();
            if (whereQStr == "ALL")
            {
                DataSet ds = new DataSet();
                ds = dataOpt.GetList("1=1 ORDER BY lastUpdateTime DESC");
                if (ds.Tables[0].Rows.Count == 0)
                {
                    return null;
                }
                else
                {
                    for (int i = 0; i <= howMany; i++)
                    {
                        myListOperators.Add(ReadLog(Convert.ToDecimal(ds.Tables[0].Rows[i]["id"])));
                    }
                    return myListOperators;
                }
            }
            else
            {
                DataSet ds = new DataSet();
                ds = dataOpt.GetList(whereQStr);
                if (ds.Tables[0].Rows.Count == 0)
                {
                    return null;
                }
                else
                {
                    for (int i = 0; i <= howMany; i++)
                    {
                        myListOperators.Add(ReadLog(Convert.ToDecimal(ds.Tables[0].Rows[i]["id"])));
                    }
                    return myListOperators;
                }
            }
        }
        
    }
}
